# Copyright (c) 2024, lanlian and contributors
# For license information, please see license.txt

from ast import If
from webbrowser import get
import frappe
from frappe.core.doctype.user.user import User
from frappe.model.document import Document
from frappe.permissions import add_user_permission
import requests
import json
from frappe import _, format_value, get_doc, msgprint
from frappe.utils import now, add_to_date, get_date_str, today, validate_email_address, cint
import datetime
from ems.equipment_managerment_system.erp_sync import K3CloudSync
from frappe.model.mapper import get_mapped_doc


class ServerConfig(Document):

    def validate(self):
        if self.disable == 0:
            num = frappe.db.count('Server Config', {'disable': 0})
            if num > 1:
                frappe.throw('为了数据准确,只允许有一个在启用的服务器配置!请禁用之前的配置!')


# 从ERP同步计量单位:
@frappe.whitelist()
def sync_uom_from_erp():
    doc_name = frappe.db.get_all(
        "ERP Sync Config",
        filters={'fname': '计量单位', 'enable': 1},
    )
    # 增加一个if判断,避免sync = K3CloudSync(doc_name[0].name)时 IndexError: list index out of range
    if doc_name:
        sync = K3CloudSync(doc_name[0].name)
        sync.sync()

# 从ERP同步物料
@frappe.whitelist()
def sync_material_from_erp():
    doc_name = frappe.db.get_list(
        "ERP Sync Config",
        filters={'fname': '物料主数据', 'enable': 1},
        fields=['name'], ignore_permissions=True
    )
    # 增加一个if判断,避免sync = K3CloudSync(doc_name[0].name)时 IndexError: list index out of range
    if doc_name:
        sync = K3CloudSync(doc_name[0].name)
        sync.sync()


# 从ERP同步供应商:
@frappe.whitelist()
def sync_supplier_from_erp():
    doc_name = frappe.db.get_all(
        "ERP Sync Config",
        filters={'fname': '供应商主数据', 'enable': 1},
        fields=['name'], 
    )
    # 增加一个if判断,避免sync = K3CloudSync(doc_name[0].name)时 IndexError: list index out of range
    if doc_name:
        sync = K3CloudSync(doc_name[0].name)
        sync.sync()


# 登录验证:校验服务器配置是否有效
@frappe.whitelist()
def login_validate(server_url, acctid, user_name, user_password): 
    # login_url 是登录函数的URL,
    login_url = server_url + "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc"
	# 构建登录接口的传参
    login_data={"acctid": acctid, "username": user_name, "password":user_password ,"lcid": 2052}
    # 验证URL及参数
    # frappe.msgprint(f'the login_data is {login_data}')
    login_response = requests.post(url=login_url, data=login_data)
    return login_response.json()["Message"] if login_response.json()["Message"] else 'OK'


# 登录并且返回cookies
@frappe.whitelist()
def login_k3cloud(server_url, acctid, user_name, user_password):
    login_url = server_url + "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc"
    login_data={"acctid": acctid, "username": user_name, "password":user_password ,"lcid": 2052}
    login_response = requests.post(url=login_url, data=login_data)
    if login_response.json()["LoginResultType"] == 1:
        # 返回cookies
        return login_response.cookies
    # return login_response


# 从ERP同步物料--One By One
@frappe.whitelist()
def get_material_from_erp(material_number):
    server_config = frappe.db.get_list('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'], ignore_permissions=True)   
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)

    if login_response:
        query_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"
        
        post_options = {"data": json.dumps({
                    "FormId": "BD_MATERIAL",
                    "FieldKeys": "FMATERIALID, FErpClsID, FNumber, FName, FSpecification, FBaseUnitId.FName",
                    "FilterString": f" FNumber = '{material_number}' "
                })
        }
        query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
        res = json.loads(query_response.text)
        
        if res:
            fmaterialid, erp_clsid, material_number, material_name, material_model, uom_name = res[0][0], res[0][1], res[0][2], res[0][3], res[0][4], res[0][5]
            if frappe.db.exists("SRM Material", {"material_number": material_number}):
                doc = frappe.get_doc("SRM Material", material_number)
                doc.material_name = res[0][3].strip()
                doc.material_model = res[0][4].strip()
                doc.save(ignore_permissions=True)
                r = '已经存在该编码!只同步名称和规格描述'
            else:
                if not frappe.db.exists('SRM UOM', uom_name):
                    add_uom_from_erp(uom_name)
                doc = frappe.get_doc({'doctype':'SRM Material', 'material_number': material_number, 'material_name': material_name, 'material_model': material_model, 'uom': uom_name, 'fmaterialid': fmaterialid, 'erp_clsid': erp_clsid })
                doc.insert(ignore_permissions=True)
                r = '手动同步成功'
            frappe.db.commit()
            return r
        else:
            frappe.msgprint('未能从ERP获取该编码!请检查录入项FNumber')


# 从ERP同步物料--初始化使用
@frappe.whitelist()
def init_sync_material_from_erp(material_id):
    server_config = frappe.db.get_list('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'], ignore_permissions=True)   
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)

    if login_response:
        query_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"
        
        post_options = {"data": json.dumps({
                # 以下参数直接从云星空的WEB API中复制
                    "FormId": "BD_MATERIAL",
                    "FieldKeys": "FMATERIALID, FErpClsID, FNumber, FName, FSpecification, FBaseUnitId.FName",
                    "FilterString": f" FMATERIALID = {material_id}"
                })
        }
        # 返回是list
        query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
        # 将json格式数据转换为字典
        res = json.loads(query_response.text)
        
        if res:
            fmaterialid, erp_clsid, material_number, material_name, material_model, uom_name = res[0][0], res[0][1], res[0][2], res[0][3], res[0][4], res[0][5]
            if frappe.db.exists("SRM Material", {"material_number": material_number}):
                doc = frappe.get_doc("SRM Material", frappe.db.exists("SRM Material", {"material_number": material_number}))
                if doc.material_name == material_name.strip() and doc.material_model == material_model.strip():
                    pass
                else:
                    doc.material_name = material_name.strip()
                    doc.material_model = material_model.strip()
                    doc.save(ignore_permissions=True)
            else:
                if not frappe.db.exists('SRM UOM', uom_name):
                    add_uom_from_erp(uom_name)
                doc = frappe.get_doc({'doctype':'SRM Material', 'material_number': material_number, 'material_name': material_name, 'material_model': material_model, 'uom': uom_name, 'fmaterialid': fmaterialid, 'erp_clsid': erp_clsid })
                doc.insert()
                frappe.db.commit()
                # if not frappe.db.exists('SRM Material Group', res[i][3]):
                #     add_material_group_from_erp(res[i][3])
                

# 从ERP获取待同步物料的MaterialID--初始化使用
@frappe.whitelist()
def get_material_id_from_erp(startrow):
    server_config = frappe.db.get_list('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'], ignore_permissions=True)   
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)

    if login_response:
        query_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"
        
        post_options = {"data": json.dumps({
                # 2023-04-20: 只获取物料编码, 名称, 规格
                    "FormId": "BD_MATERIAL",
                    "FieldKeys": "FMATERIALID, FNumber, FName, FSpecification, FBaseUnitId.FName, FErpClsID",
                    "FilterString": " FDocumentStatus = 'C' AND FIsPurchase = 1 AND FForbidStatus = 'A' AND FErpClsID NOT in (5, 9)",
                    "StartRow": startrow,
                    "Limit": 2000
                })
        }
        # 返回是list
        query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
        # 将json格式数据转换为字典
        res = json.loads(query_response.text)
        
        if res:
            return res



# 从ERP同步供应商--One By One
@frappe.whitelist()
def get_supplier_from_erp(supplier_number):
    server_config = frappe.db.get_list('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'], ignore_permissions=True)   
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)

    if login_response:
        query_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"
        
        post_options = {"data": json.dumps({
                # FilterString中有个小细节:{变量名}一定要在引号里面!坑！坑！坑！
                    "FormId": "BD_Supplier",
                    "FieldKeys": "FGroup, FNumber, FName, FCorrespondOrgId.FNumber, FSOCIALCRECODE, FContact, FEMail, FTel, FMobile",
                    "FilterString": f" FNumber = '{supplier_number}' "
                })
        }
        # 返回是list
        query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
        # 将json格式数据转换为字典
        res = json.loads(query_response.text)
        
        if res:
            group, supplier_number, supplier_name, org, tax_identify, full_name, email_address, phone, mobile_phone = res[0][0], res[0][1], res[0][2], res[0][3], res[0][4], res[0][5], res[0][6], res[0][7], res[0][8]
            if frappe.db.exists("SRM Supplier", {"supplier_number": supplier_number}):
                frappe.msgprint('已经存在该编码!')
            elif email_address:
                doc = frappe.get_doc({
                                        'doctype':'SRM Supplier', 
                                        'supplier_number': supplier_number, 
                                        'supplier_name': supplier_name, 
                                        'org': org, 
                                        'tax_identify': tax_identify,
                                        'contact': [{
                                            'full_name': full_name if full_name else 'A',
                                            'email_address': email_address,
                                            'phone': phone if phone else '',
                                            'mobile_phone': mobile_phone if mobile_phone else ''
                                        }]
                })
                doc.insert()
                frappe.db.commit()
            else:
                doc = frappe.get_doc({
                                        'doctype':'SRM Supplier', 
                                        'supplier_number': supplier_number, 
                                        'supplier_name': supplier_name, 
                                        'org': org, 
                                        'tax_identify': tax_identify,
                })
                doc.insert()
                frappe.db.commit()                
        else:
            frappe.msgprint('未能从ERP获取该编码!请检查录入项FNumber')


# 从ERP获取待同步供应商的SupplierID--初始化使用
@frappe.whitelist()
def get_supplier_id_from_erp(startrow):
    server_config = frappe.db.get_list('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'], ignore_permissions=True)   
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)

    if login_response:
        query_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc"
        
        post_options = {"data": json.dumps({
                # 以下参数直接从云星空的WEB API中复制
                    "FormId": "BD_Supplier",
                    "FieldKeys": "FNumber",          # FSupplierId, FName
                    "FilterString": " FDocumentStatus = 'C' AND FForbidStatus = 'A'",
                    "StartRow": startrow,
                })
        }
        # 返回是list
        query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
        # 将json格式数据转换为字典
        res = json.loads(query_response.text)
        
        if res:
            return res


@frappe.whitelist()
def my_requests(query_url):
    # pass
    # query_response = requests.post(url=query_url, data=post_options, cookies=login_response)
    # 将json格式数据转换为字典
    # res = json.loads(query_response.text)
    return query_url

# 生成EMS备件出库
@frappe.whitelist()
def make_stock_entry(source_name, stock_entry_type, source_warehouse=None):
    fault_repair = frappe.get_doc("EMS Fault Repair", source_name)
    if not source_warehouse:
        source_warehouse = frappe.db.get_single_value('EMS Settings', 'source_warehouse')
    stock_entry = frappe.new_doc("Stock Entry")
    stock_entry.stock_entry_type = stock_entry_type
    stock_entry.company = fault_repair.company
    stock_entry.remarks = fault_repair.name
    for row in fault_repair.parts_item:
        stock_entry.append("items", {"s_warehouse": source_warehouse, "item_code": row.item_code, "qty": row.qty, "stock_uom": row.uom})

    return stock_entry.as_dict()

# 生成k3cloud其他应付单
@frappe.whitelist()
def sync_to_k3cloud_ap_otherpayable(docname):
    doc = frappe.get_doc('EMS Acceptance Settlement', docname)
    print(doc)
    # 从EMS设置表取得常量值(默认值), Make Sure Success Sync to k3cloud
    expense_item = frappe.db.get_single_value('EMS Settings', 'expense_item')
    print(expense_item)
    department_no = frappe.db.get_single_value('EMS Settings', 'department_no')
    print(department_no)
    default_org_no = frappe.db.get_single_value('EMS Settings', 'default_org_no')
    print(default_org_no)
    custom_supplier_number = frappe.get_doc('Supplier', doc.supplier).custom_supplier_number
    print(custom_supplier_number)
    server_config = frappe.db.get_all('Server Config', filters = {'disable': 0}, fields = ['server_url', 'user_name', 'acctid', 'user_password'])
    login_response = login_k3cloud(server_config[0].server_url, server_config[0].acctid, server_config[0].user_name, server_config[0].user_password)
    if login_response:
        # 构建保存接口URL
        save_url = server_config[0].server_url + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc"
        
    post_options = {
        "Model": {
            # 往来单位类型: BD_Supplier, 供应商
            "FCONTACTUNITTYPE": "BD_Supplier",
            # 供应商编码
            "FCONTACTUNIT": {"FNumber": custom_supplier_number}, # 
            # 含税金额
            "FTOTALAMOUNTFOR_H": doc.total_cost,
            "FNOTSETTLEAMOUNTFOR": doc.total_cost,
            # 结算组织, 付款组织, 采购组织
            "FSETTLEORGID": {"FNumber": default_org_no}, # 
            "FPURCHASEORGID": {"FNumber": default_org_no}, # 
            "FPAYORGID": {"FNumber": default_org_no}, # 
            # 汇率, 不含税金额, 税额
            "FExchangeRate": 1.0,
            "FNOTAXAMOUNT": doc.amount_no_tax,
            "FTAXAMOUNT": doc.tax_amount,
            # 明细表: 费用项目, 费用承担部门, 税率, 不含税金额, 税额, 含税金额, 含税金额本位币, 不含税金额本位币, 税额本位币
            "FEntity": [
                {
                    "FCOSTID": {"FNumber": expense_item}, # 
                    "FCOSTDEPARTMENTID": {"FNumber": department_no}, # 
                    "FEntryTaxRate": doc.tax_rate,
                    "FNOTAXAMOUNTFOR": doc.amount_no_tax,
                    "FTAXAMOUNTFOR": doc.tax_amount,
                    "FTOTALAMOUNTFOR": doc.total_cost,
                    "FNOTSETTLEAMOUNTFOR_D": doc.total_cost,
                    "FNOTAXAMOUNT_D": doc.amount_no_tax,
                    "FTAXAMOUNT_D": doc.tax_amount,
                }
            ]
        }
    }
    post_data = { "FormID": "AP_OtherPayable", "Data": json.dumps(post_options) }
    print(post_data)
    save_response = requests.post(url = save_url, data = post_data, cookies = login_response)
    r = json.loads(save_response.text)
    if r["Result"]["ResponseStatus"]["IsSuccess"] == True:
        back_billno = r["Result"]["Number"]
        frappe.db.set_value(doc.doctype, doc.name, {"erp_billno": back_billno})
        doc.reload()
        frappe.msgprint(f"同步ERP成功, 单号: ${back_billno}")
        return back_billno
    else:
        frappe.msgprint(r["Result"]["ResponseStatus"]["Errors"][0]["Message"])